﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Staticage.Core {

    public static class Preconditions {

        public static void CheckArgument(bool expression) {
            if (!expression) {
                throw new ArgumentException();
            }
        }

        public static void CheckArgument(bool expression, object errorMessage) {
            if (!expression) {
                throw new ArgumentException(Strings.ValueOf(errorMessage));
            }
        }

        public static void CheckArgument(bool expression, string errorMessageTemplate, params object[] errorMessageArgs) {
            if (!expression) {
                throw new ArgumentException(Strings.Format(errorMessageTemplate, errorMessageArgs));
            }
        }

        public static T CheckNotNull<T>(this T reference) {
            if (reference == null) {
                throw new ArgumentNullException();
            }
            return reference;
        }

        public static T CheckNotNull<T>(this T reference, string paramName) {
            
            if (reference == null) {
                throw new ArgumentNullException(paramName);
            }
            return reference;
        }

        public static int CheckElementIndex(int index, int size) {
            return CheckElementIndex(index, size, "index");
        }

        public static int CheckElementIndex(int index, int size, string desc) {
            // Carefully optimized for execution by hotspot (explanatory comment above)
            if (index < 0 || index >= size) {
                throw new ArgumentOutOfRangeException(BadElementIndex(index, size, desc));
            }
            return index;
        }

        private static string BadElementIndex(int index, int size, string desc) {
            if (index < 0) {
                return Strings.Format("%s (%s) must not be negative", desc, index);
            }
            else if (size < 0) {
                throw new ArgumentException("negative size: " + size);
            }
            else {
                return Strings.Format("%s (%s) must be less than size (%s)", desc, index, size);
            }
        }
    }
}
